package com.plugin.sproutcore.ui.widgets;

import java.lang.reflect.Method;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;

import com.plugin.sproutcore.core.validator.IValidate;
import com.plugin.sproutcore.util.ProjectUtil;

public class ProjectBrowserController implements IValidate
{
	private IResource _file;
	private IContainer _root;
	private Object _dialogPage;
	
	public ProjectBrowserController(Object dialog, IResource project)
	{
		this._file = project;
		this._dialogPage = dialog;
	}

	/**
	 * Uses the standard container selection dialog to choose the new value for
	 * the container field.
	 * @throws CoreException 
	 */
	public void handleBrowse() throws CoreException 
	{
		Shell shell = null;
		Method method;
		try 
		{
		  method = _dialogPage.getClass().getMethod("getControl");
		  Control control = (Control)method.invoke(_dialogPage);
		  shell = control.getShell();
		} 
		catch (Exception e) 
		{
			IStatus status = ProjectUtil.createErrorStatus(e.getMessage());
			throw new CoreException(status);
		}
		
		ContainerSelectionDialog dialog = new ContainerSelectionDialog(
				shell, 
				getRoot(), false,
				"Select project");
		dialog.showClosedProjects(false);
		if (dialog.open() == ContainerSelectionDialog.OK) 
		{
			Object[] result = dialog.getResult();
			if (result.length == 1) 
			{
				IPath path = (Path) result[0];
				IResource resource = null;
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				try {
					resource = root.getProject(path.toString());
				}
				catch (IllegalArgumentException e) {
					resource = root.getFile(path);
				}
				// Now that we have the file, find out if it is a sprout core 
				// project or is contained by a sprout core project.
				if (resource != null) 
				{
					resource = getSproutCoreProject(resource);
					_file = resource;
				}
			}
		}
	}

	public void validate(List<IStatus> errors) 
	{
		if (getResource() == null) 
		{
			IStatus status = ProjectUtil.createErrorStatus("Select a project which contains a SproutCore nature.");
			errors.add(status);
		}
	}
	
	private IResource getSproutCoreProject(IResource resource) 
	throws CoreException
	{
		if (resource instanceof IContainer)
		{
			IContainer container = (IContainer) resource;
			IResource[] containerMembers = container.members();
			for (IResource r:containerMembers)
			{
				String path = r.getName();
				// SproutCore projects must have a buildFile in it
				if (path.equals("Buildfile")) {
					return r.getParent();
				}
			}
		}
		return getSproutCoreProject(resource.getParent());
	}
	
	public void setResource(IResource file)
	{
		_file = file;
	}
	public IResource getResource()
	{
		return _file;
	}
	
	public IContainer getRoot()
	{
		if (_root == null) {
			_root = ResourcesPlugin.getWorkspace().getRoot();
		}
		return _root;
	}
	public void setRoot(IContainer root)
	{
		_root = root;
	}
}
